PowerShellスクリプト一発でツールのダウンロード&サイレントインストールを行う
AWS CloudFormationでWindowsインスタンスの環境を整える事について
AWS上で環境の構築を行う上ではCloudFormationは既に欠かせないサービスとなっております。手作業で行えば時間の掛かる作業がコマンド1発で全て揃ってしまうというのは実に魅力的なものであります。繰り返し行う作業だったり、数多くこなすような必要性がある場合等は特にその効果を発揮します。
EC2サーバ構築の際、CloudFormationではサーバの起動と併せて各種アプリケーションやツールのインストールも行う事が出来ます。この辺りはChef等を用いても実現する事が出来ますが、CloudFormationで諸々ツールまで導入出来るというのは何ともすごいものです。
私もこの機能は存分に使わせて頂いており、Linuxベースのものについては全面的に利用させてもらっております。....がしかし!WindowsOSのEC2インスタンスについてCloudFormationを使う場合は、インスタンス作成まではLinuxベースのものと特に変わらずスムーズに作成出来るのですが、その他ツールのインストールやアプリケーションの環境構築については若干手間と時間が掛かる印象。単にCloudFormationでその辺の処理を行う事に慣れていない・場数を踏んでいないだけなのかもしれないですが、
- コマンドラインで全て行えない操作がある(あるのかもしれないけど現状把握仕切っていない)
- Linuxベースで行う場合と勝手が異なるところがある
- 起動後ログイン可能となるまでに時間が掛かる(凡そ15分程掛かる)のでトライアンドエラーでCloudFormationを作り上げる場合は若干待たされる事になりもんにょりする
と言うような躓きポイントがあり、若干心折れる局面も時折あったり。
ブログでもWindowsインスタンス作成及びツールの導入まで行っているエントリもあったり、またWeb全般を見渡してもWindowsインスタンスの環境導入迄行っているエントリは存在はするものの、そこまで多くない印象です。
- ワンクリックでお試しSelenium Server編|アドカレ2013 : CFn #2 | Developers.IO
- Bootstrapping AWS CloudFormation Windows Stacks - AWS CloudFormation
- CloudFormation with Windows Bootstrapping - Synaptian
- AWS CloudFormation のテンプレート - AWS CloudFormation(AWS リソース作成テンプレート) | アマゾン ウェブ サービス(AWS 日本語)
まずはPowerShellでどこまで出来るか、試してみよう
一方、Windows環境には『PowerShell』というものが用意されています。調べてみるとやりたいことが粗方実現出来そうでしたので、
- インスタンス作成までは従来通りCloudFormationを使って行う(この辺までならLinuxインスタンス同様、何ら難しい事無く出来る)
- Windowsインスタンス起動・ログイン後に『諸々インストールや設定を行う』PowerShellスクリプトを実行
という風にやるんでも良いのでは無いか?ベストはCloudFormarionで全て一発実行だが、そこに行くまでの代替案として二段構えの上記手法でも良いのでは無いか?(Linuxベースに比べて手動作業が多くなるWindows環境下では、これでも十分作業の効率化になるのでは?)と思うようになりました。
という訳で、PowerShellでどんな事が出来るのか、どういう風にやればいいのかを簡単ではありますがまとめてみました。
PowerShellでファイル実行を行う際の事前準備
WindowsインスタンスをAWSで構築した後、その環境下でPowerShellスクリプトを実行する際には幾つか手順・作業が必要となります。
まずはPowerShell起動について。管理者権限での実行を必要とするので、[Windows] -> [スタート] -> [Windows PowerShell]を管理者で実行します(右クリックで選べます)。
リージョン選択を求められるので値を入力し決定。
Initialize-AWSDefaults: Credentials for this shell were set using instance profile Specify region Please choose one of the following regions to use or specify one by system name [] <Specify a different region> [] us-east-1 [] us-west-1 [] us-west-2 [] eu-west-1 [] ap-northeast-1 [] ap-southeast-1[] ap-southeast-2 [] sa-east-1 [] us-gov-west-1 [] cn-north-1 [?] ヘルプ (既定値は "<Specify a different region>"):us-west-2 Default credentials and/or region have been stored to 'AWS PS Default' and set active for this shell. PS C:\Program Files (x86)\AWS Tools\PowerShell\AWSPowerShell>
ちなみにリージョンを変更する場合はこの辺をご参照ください。
PowerShellでファイルのダウンロードを行う
インストーラや各種ファイルをダウンロードする際のコマンドです。
Parameter Set: Default Invoke-WebRequest [-Uri] <Uri> [-Body <Object> ] [-Certificate <X509Certificate> ] [-CertificateThumbprint <String> ] [-ContentType <String> ] [-Credential <PSCredential> ] [-DisableKeepAlive] [-Headers <IDictionary> ] [-InFile <String> ] [-MaximumRedirection <Int32> ] [-Method <WebRequestMethod> ] [-OutFile <String> ] [-PassThru] [-Proxy <Uri> ] [-ProxyCredential <PSCredential> ] [-ProxyUseDefaultCredentials] [-SessionVariable <String> ] [-TimeoutSec <Int32> ] [-TransferEncoding <String> ] [-UseBasicParsing] [-UseDefaultCredentials] [-UserAgent <String> ] [-WebSession <WebRequestSession> ] [ <CommonParameters>]
PowerShellで『サイレントインストール』を行う
こういう手法があるというのは先のCloudFormationによるSelenium環境導入エントリ(byもっちー)にて知るようになりました。今回のエントリ及びPowerShellでの実行の際にはこの手法を用いる事にします。
『サイレントインストール』については、残念ながら共通の手段・シンタックスは無い模様。ツールやアプリケーションによって諸々異なるようです。『ツールやアプリケーション』+『サイレントインストール(silent install)』辺りでググって手段を見つける他無さそうな感じです。
PowerShellでレジストラを操作する
- PowerShellスクリプトの実行セキュリティ・ポリシーを変更する - @IT
- PowerShellでレジストリ情報を操作する - @IT
- Windows PowerShellコマンド&スクリプティング入門:PowerShellの基本(前編) (5/5) - @IT
レジストラを操作出来ちゃえるというのは若干闇感漂うような気もしますが、PowerShellではこのような事も出来るんですね。
PowerShellスクリプトの作成・実行
今回、起動したWindowsインスタン上で揃えたい環境はこちら。
- 行いたい操作操作:
- ツールダウンロード用フォルダ(C:¥tools¥)を作成
- Firefoxのダウンロード&サイレントインストール
- Tableau Desktopのダウンロード&サイレントインストール
- PostgreSQL ODBCドライバのダウンロード&所定フォルダへの解凍
- OSレジストリに新しい値を追加
そして、今回用意したPowerShellスクリプトファイルがこちら。
AutoDLandInstall.ps1
#make Directory for tools mkdir C:\tools # Firefox Download & Install Invoke-WebRequest -Uri "https://download.mozilla.org/?product=firefox-28.0-SSL&os=win&lang=ja" -OutFile C:\tools\firefox.exe C:\tools\firefox.exe -ms # Tableau Desktop Download & Install Invoke-WebRequest -Uri "https://downloads.tableausoftware.com/tssoftware/TableauDesktop-64bit.exe" -OutFile C:\tools\TableauDesktop.exe C:\tools\TableauDesktop.exe /q:a /c:"setup /q" # PostgreSQL ODBC Driver Download & Unzip Invoke-WebRequest -Uri "http://ftp.postgresql.org/pub/odbc/versions/msi/psqlodbc_09_03_0210.zip" -OutFile C:\tools\psqlodbc_09_03_0210.zip mkdir C:\tools\psqlodbc_09_03_0210 $sh = New-Object -ComObject Shell.Application $unzipDirObj = $sh.NameSpace("C:\tools\psqlodbc_09_03_0210\") $zipPathObj = $sh.NameSpace("C:\tools\psqlodbc_09_03_0210.zip") $unzipDirObj.CopyHere($zipPathObj.Items()) # 注:実はこのmxiexecによるサイレントインストールのみ、上手く行かない。何でだろう... msiexec.exe /i C:\tools\psqlodbc_09_03_0210\psqlodbc.msi /qn # Add Value to Windows OS Registory Set-ItemProperty -Path HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\ -Name KeepAliveTime -Value 30000 -Type DWORD Set-ItemProperty -Path HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\ -Name KeepAliveInterval -Value 1000 -Type DWORD Set-ItemProperty -Path HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\ -Name TcpMaxDataRetransmissions -Value 10 -Type DWORD
Windowsインスタンスにログイン後、管理者権限でPowerShellを起動&リージョンを設定。
そして今回、S3バケット上記のファイルをアップロードしておき、そのファイルをPowerShellを介してダウンロード。
Invoke-WebRequest -Uri "https://s3-ap-northeast-1.amazonaws.com/xxxxxxxxxxx/AutoDLandInstall.ps1" -OutFile C:\AutoDLandInstall.ps1
このままではファイル実行が出来ないので権限変更実施。
PS C:\> Set-ExecutionPolicy RemoteSigned 実行ポリシーの変更 実行ポリシーは、信頼されていないスクリプトからの保護に役立ちます。実行ポリシーを変更すると、about_Execution_Policies のヘルプ トピック (http://go.microsoft.com/fwlink/?LinkID=135170) で説明されているセキュリティ上の危険にさらされる可能性があります。実行ポリシーを変更しますか? [Y] はい(Y) [N] いいえ(N) [S] 中断(S) [?] ヘルプ (既定値は "Y"): Y PS C:\>
ファイル実行。デバッグ文等は特に盛り込んでませんがこれでひと通りの処理が完了します。
PS C:\> .\AutoDLandInstall.ps1
まとめ
以上、PowerShellによる環境導入自動化スクリプト作成について書いてみました。書いてて思ったのですが、Windowsインスタンス作成後に上記で作成したPowerShellスクリプトファイルをダウンロードして実行させるようにすればCloudFormationでも記述が複雑化しなくて済むんじゃね?とふと思いました。今度試してみよう。